package com.yilin.tms.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yilin.commons.exception.BusinessException;
import com.yilin.commons.util.ArrayUtil;
import com.yilin.commons.util.CommonUtil;
import com.yilin.commons.util.DateTimeUtil;
import com.yilin.commons.util.StringUtil;
import com.yilin.tms.core.application.AppUtil;
import com.yilin.tms.core.application.PageData;
import com.yilin.tms.core.commons.utils.ParamUtil;
import com.yilin.tms.core.commons.utils.QueryUtil;
import com.yilin.tms.core.entity.capital.BankCard;
import com.yilin.tms.core.entity.truck.TruckVehicle;
import com.yilin.tms.core.entity.user.OrganType;
import com.yilin.tms.core.entity.user.account.Account;
import com.yilin.tms.core.entity.user.UserType;
import com.yilin.tms.core.entity.user.auth.*;
import com.yilin.tms.core.entity.user.organize.Cooperate;
import com.yilin.tms.core.entity.user.organize.Organize;
import com.yilin.tms.core.entity.user.organize.UserRole;
import com.yilin.tms.core.remote.ICapitalRemote;
import com.yilin.tms.core.remote.IMessageRemote;
import com.yilin.tms.core.remote.IVehicleRemote;
import com.yilin.tms.user.service.*;
import com.yilin.tms.user.mapper.AccountMapper;
import com.yilin.tms.user.mapper.CooperateMapper;
import com.yilin.tms.user.mapper.OrganizeMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author liuxu :)
 * @version 1.0
 * @date 2022-10-24 0024
 */
@Service
public class OrganizeService extends ServiceImpl<OrganizeMapper, Organize> implements IOrganizeService{
    @Resource
    private IAccountService accountService;
    @Resource
    private IRoleService roleService;
    @Resource
    private IMemberTypeService memberTypeService;
    @Resource
    private IAuthService authService;

    @Resource
    private IVehicleRemote vehicleRemote;
    @Resource
    private CooperateMapper cooperateMapper;
    @Resource
    private OrganizeMapper organizeMapper;
    @Resource
    private AccountMapper accountMapper;

    @Resource
    private IMessageRemote messageRemote;
    @Resource
    private ICapitalRemote capitalRemote;

    /**
     * 客户注册通道
     */
    @Override
    public void organizeRegister(Organize organize, Account account) {
        QueryWrapper<Organize> queryWrapper;
        /// ### 检查组织名称
        if (StringUtil.isNotEmpty(organize.getOrganizeName())) {
            queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("organize_name", organize.getOrganizeName());
            if (organizeMapper.selectOne(queryWrapper) != null) {
                throw new BusinessException("注册的组织信息已存在，不要重复注册！");
            }
        }
        /// ### 检查账户信息是否存在
        Account extAccount = accountService.getAccountByUsername(account.getUsername());
        if (extAccount != null) throw new BusinessException("注册的账号已存在，不要重复注册！");
        Account pheAccount = accountService.getAccountByPhone(account.getPhone(), account.getUserType());
        if (pheAccount != null) throw new BusinessException("该手机号已被注册！请直接登录或更换手机号");
        // ### 如果存在手机号相同的已删除账号，采用账户覆盖，不重新建立账户，部分信息，如认证功能会得到恢复
        List<Account> phoneAccList = accountService.getLogicAccountByPhone(account.getPhone());
        if (phoneAccList.size() > 0) {
            account.setId(ArrayUtil.first(phoneAccList).getId());
            accountMapper.recoveryById(account.getId());
        }
        organize.setCreateTime(new Date());
        organize.setOrganizeTel(account.getPhone());
        organizeMapper.insert(organize);
        //组织创建成功，初始化角色
        UserRole role = roleService.initManagerRole(organize);
        account.setOrganizeId(organize.getId());
        account.setOrganizeName(organize.getOrganizeName());
        account.setRoleName(role.getName());
        account.setUserState(Account.UserState.enable);
        account.setSuperiorPlatId(organize.getSuperiorPlatOrganizeId());
        account.setSuperiorPlatName(organize.getSuperiorPlatOrganizeName());
        //密码MD5加密
        account.setPassword(AppUtil.md5(account.getPassword()));
        if (account.getId()==null) accountMapper.insert(account);
        else accountMapper.updateById(account);

        organize.setManagerUserId(account.getId());
        organize.setManagerUserName(account.getName());
        organize.setManagerUserPhone(account.getPhone());
        organizeMapper.updateById(organize);

        //设置自己为管理员
        account.setOrganizeManagerUserId(account.getId());
        account.setOrganizeManagerUserName(account.getName());
        accountMapper.updateById(account);
    }

    /**
     * 找查 组织ID
     */
    @Override
    public Organize getOrganizeById(String organizeId) {
        if (organizeId == null) throw new BusinessException("组织ID不能为空！");
        QueryWrapper<Organize> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", organizeId);
        List<Account> employeeList = accountService.getEmployeeByOrganizeId(organizeId);
        Organize organize = organizeMapper.selectOne(queryWrapper);
        int totalGoodAppraiseCount = 0, totalMidAppraiseCount = 0, totalBadAppraiseCount = 0;
        int totalComplaintsCount = 0, totalArbitrationCount = 0, totalViolationCount = 0;
        for (Account account : employeeList) {
            totalGoodAppraiseCount += account.getGoodAppraiseCount();
            totalMidAppraiseCount += account.getMidAppraiseCount();
            totalBadAppraiseCount += account.getBadAppraiseCount();
            totalComplaintsCount += account.getComplaintsCount();
            totalArbitrationCount += account.getArbitrationCount();
            totalViolationCount += account.getViolationCount();
        }
        if (organize != null){
            organize.setTotalGoodAppraiseCount(totalGoodAppraiseCount);
            organize.setTotalMidAppraiseCount(totalMidAppraiseCount);
            organize.setTotalBadAppraiseCount(totalBadAppraiseCount);
            organize.setTotalComplaintsCount(totalComplaintsCount);
            organize.setTotalArbitrationCount(totalArbitrationCount);
            organize.setTotalViolationCount(totalViolationCount);
        }
        return organize;
    }

    /**
     * 获取会员级别下的所有组织
     */
    @Override
    public List<Organize> getOrganizeListByMemberTypeId(String memberTypeId) {
        QueryWrapper<Organize> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("member_type_id", memberTypeId);
        return organizeMapper.selectList(queryWrapper);
    }

    /**
     * 获取集团组织列表
     * 这里获取的是集团
     */
    @Override
    public List<Organize> getGroupOrganizeList(String groupOrganizeId) {
        QueryWrapper<Organize> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("group_organize_id", groupOrganizeId);
        return organizeMapper.selectList(queryWrapper);
    }

    /**
     * 获取所有授权组织
     * 这里获取的是运营平台 向下所有平台
     */
    @Override
    public PageData<Organize> getAuthorizedOrganizePage(Organize query, Integer page, Integer limit) {
        QueryWrapper<Organize> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("authorized", true);
        QueryUtil.andQueryWrapper(queryWrapper, query);
        return organizeMapper.selectPage(new PageData<>(page, limit), queryWrapper);
    }

    /**
     * 获取所有下级组织分页
     * 这里获取的是运营平台 向下所有平台
     */
    @Override
    public PageData<Organize> getBelowOrganizePage(Organize query, Integer page, Integer limit) {
        PageData<Organize> objectPageData = new PageData<>(page, limit);
        return organizeMapper.getBelowOrganizePage(objectPageData, query);
    }

    @Override
    public PageData<Organize> getBelowOrganizeBankCardPage(Organize query, Integer page, Integer limit) {
        PageData<Organize> objectPageData = new PageData<>(page, limit);
        PageData<Organize> pageData = organizeMapper.getBelowOrganizePage(objectPageData, query);
        if (pageData == null || pageData.getList() == null || pageData.getList().isEmpty()) return pageData;
        String[] idList = pageData.getList().stream().map(Organize::getId).toArray(String[]::new);
        List<BankCard> listBankCard = ParamUtil.isSuccess(capitalRemote.getDefaultBankCardList(idList));
        for (Organize organize : pageData.getList()) {
            BankCard sameBankCard = listBankCard.stream().filter(o -> Objects.equals(o.getOrganizeId(), organize.getId())).findFirst().orElse(null);
            if (sameBankCard == null || sameBankCard.getBankAccNo() == null) continue;
            organize.setBindBankCardName(sameBankCard.getBankName());
            organize.setBindBankCardNo(sameBankCard.getBankAccNo());
        }
        return pageData;
    }

    /**
     * 获取直下级平台公司分页
     * 这里获取的是运营平台 向下一级平台
     */
    @Override
    public PageData<Organize> getLowerOrganizePage(Organize query, Integer page, Integer limit) {
        QueryWrapper<Organize> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("superior_plat_organize_id", query.getId());
        queryWrapper.ne("user_type", UserType.shipperUser).ne("user_type", UserType.truckerUser);
        QueryUtil.andQueryWrapper(queryWrapper, query);
        return organizeMapper.selectPage(new PageData<>(page, limit), queryWrapper);
    }

    /**
     * 上级组织获取 下级组织列表
     * 这里获取的是运营平台 向下一级平台
     */
    @Override
    public List<Organize> getOrganizeListBySuperOrganizeId(String superOrganizeId) {
        if (superOrganizeId == null) throw new BusinessException("上级组织ID不能为空！");
        QueryWrapper<Organize> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("superior_plat_organize_id", superOrganizeId);
        queryWrapper.ne("user_type", UserType.shipperUser).ne("user_type", UserType.truckerUser);
        return organizeMapper.selectList(queryWrapper);
    }

    /**
     * 解散组织
     */
    @Override
    public void dismissOrganize(Account loginUser, Organize organize) {
        List<Account> employeeList = accountService.getEmployeeByOrganizeId(organize.getId());
        for (Account account : employeeList) accountService.scrapAccount(loginUser, account);
        BusinessLicense businessLicense = authService.getBusinessLicenseByOrganizeId(organize.getId());
        if (businessLicense != null) authService.deleteBusinessLicenseById(businessLicense);
        TransBusinessLicense transBusinessLicense = authService.getTransLicenseByOrganizeId(organize.getId());
        if (transBusinessLicense != null) authService.deleteTransBusinessLicense(transBusinessLicense);
        StampCompanySeal stampCompanySeal = authService.getStampCompanySealByOrganizeId(organize.getId());
        if (stampCompanySeal != null) authService.deleteStampCompanySeal(stampCompanySeal);
        StampPersonalSignet stampPersonalSignet = authService.getStampPersonalSignetByOrganizeId(organize.getId());
        if (stampPersonalSignet != null) authService.deleteStampPersonalSignet(stampPersonalSignet);
        TaxCertification taxCertification = authService.getTaxCertificationByOrganizeId(organize.getId());
        if (taxCertification != null) authService.deleteTaxCertification(taxCertification);
        String msg = "尊敬的用户您好，您的组织：%s 已成功解散，组织下的所有员工账户已注销，下次使用时需要重新注册账号！";
        String fmtMsg = String.format(msg, organize.getOrganizeName());
        messageRemote.sendPhoneMessage(loginUser.getPhone(), fmtMsg);
    }

    /***
     * 定时任务 每天
     * 月度 更新组织信用评分
     * */
    @Override
    public void monthlyUpdateRating() {
        QueryWrapper<Organize> queryWrapper = new QueryWrapper<>();
        queryWrapper.le("monthly_rating_time", DateTimeUtil.plusDay(new Date(), -30));
        List<Organize> organizeList = organizeMapper.selectList(queryWrapper);
        for (Organize organize : organizeList) {
            List<Account> employeeList = accountService.getEmployeeByOrganizeId(organize.getId());
            if (employeeList.size() >= 3) {
                //如果员工数量大于等于3，则去掉一个最高分和去掉一个最低分
                employeeList.sort((o1, o2) -> {
                    if (o1.getCredit() == null) o1.setCredit(80.0);
                    if (o2.getCredit() == null) o2.setCredit(80.0);
                    return o1.getCredit().compareTo(o2.getCredit());
                });
                employeeList.remove(0);
                employeeList.remove(employeeList.size() - 1);
            }
            double totalCredit = ArrayUtil.numListAdd(employeeList, obj -> obj.getCredit() == null ? 80 : obj.getCredit());
            organize.setMonthlyRating(CommonUtil.doubleTwo(totalCredit / employeeList.size()));
            organize.setMonthlyRatingTime(new Date());
        }
        if (organizeList.size() > 0) updateBatchById(organizeList);
    }

    //------------------------------------------合作用户区---------------------------------------------------

    /**
     * 合作申请列表
     */
    @Override
    public List<Cooperate> getUserCooperateApplyList(Account loginUser) {
        QueryWrapper<Cooperate> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("cooperate_state", Cooperate.CooperateState.applying);
        queryWrapper.and(cooperateQueryWrapper -> cooperateQueryWrapper.eq("shipper_organize_id", loginUser.getOrganizeId())
                .or().eq("trucker_organize_id", loginUser.getOrganizeId()));
        return cooperateMapper.selectList(queryWrapper);
    }

    /**
     * 发起合作
     */
    @Override
    public void applyUserCooperate(Account loginUser, String targetOrganizeId) {
        Cooperate cooperate = getCooperate(loginUser, targetOrganizeId);
        if (cooperate != null && cooperate.getCooperateState() == Cooperate.CooperateState.cooperate) {
            throw new BusinessException("您和该用户已建立合作");
        }
        Organize targetOrganize = getOrganizeById(targetOrganizeId);
        if (cooperate == null) cooperate = new Cooperate();
        if (loginUser.getUserType() == UserType.shipperUser) {
            cooperate.setShipperOrganizeId(loginUser.getOrganizeId());
            cooperate.setShipperOrganizeName(loginUser.getOrganizeName());
            cooperate.setShipperOrganizeLogo(loginUser.getOrganizeLogo());
            cooperate.setTruckerOrganizeId(targetOrganize.getId());
            cooperate.setTruckerOrganizeName(targetOrganize.getOrganizeName());
            cooperate.setTruckerOrganizeLogo(targetOrganize.getOrganizeLogo());
        } else if (loginUser.getUserType() == UserType.truckerUser) {
            cooperate.setShipperOrganizeId(targetOrganize.getId());
            cooperate.setShipperOrganizeName(targetOrganize.getOrganizeName());
            cooperate.setShipperOrganizeLogo(targetOrganize.getOrganizeLogo());
            cooperate.setTruckerOrganizeId(loginUser.getOrganizeId());
            cooperate.setTruckerOrganizeName(loginUser.getOrganizeName());
            cooperate.setTruckerOrganizeLogo(loginUser.getOrganizeLogo());
        }
        cooperate.setCreateTime(new Date());
        cooperate.setInitiatorUserId(loginUser.getId());
        cooperate.setInitiatorUserName(loginUser.getName());
        cooperate.setInitiatorUserType(loginUser.getUserType());
        cooperate.setCooperateState(Cooperate.CooperateState.applying);
        if (cooperate.getId() == null) cooperateMapper.insert(cooperate);
        else cooperateMapper.updateById(cooperate);
    }

    /**
     * 同意合作
     */
    @Override
    public void agreeCooperateApply(Account loginUser, String cooperateId) {
        Cooperate cooperate = cooperateMapper.selectById(cooperateId);
        if (cooperate != null && cooperate.getCooperateState() == Cooperate.CooperateState.cooperate) {
            throw new BusinessException("您和该用户已建立合作");
        }
        if (cooperate == null || cooperate.getCooperateState() == Cooperate.CooperateState.none) {
            throw new BusinessException("该合作申请已被取消");
        }
        Account account = accountMapper.selectById(cooperate.getInitiatorUserId());
        if (account.getUserType() == loginUser.getUserType()) throw new BusinessException("您无法同意自己对他人的申请");
        if (loginUser.getUserType() == UserType.shipperUser) {
            if (!cooperate.getShipperOrganizeId().equals(loginUser.getOrganizeId())) {
                throw new BusinessException("您不是合作对象");
            }
        } else if (loginUser.getUserType() == UserType.truckerUser) {
            if (!cooperate.getTruckerOrganizeId().equals(loginUser.getOrganizeId())) {
                throw new BusinessException("您不是合作对象");
            }
        }
        cooperate.setAgreementUserId(loginUser.getId());
        cooperate.setAgreementUserName(loginUser.getName());
        cooperate.setCooperateState(Cooperate.CooperateState.cooperate);
        cooperate.setCooperateTime(new Date());
        cooperateMapper.updateById(cooperate);
    }

    /**
     * 取消或拒绝合作
     */
    @Override
    public void refuseCooperate(Account loginUser, String targetOrganizeId) {
        Cooperate cooperate = getCooperate(loginUser, targetOrganizeId);
        if (cooperate == null || cooperate.getCooperateState() == Cooperate.CooperateState.none) {
            throw new BusinessException("你和该用户未建立合作");
        }
        cooperate.setCooperateState(Cooperate.CooperateState.none);
        cooperateMapper.updateById(cooperate);
    }

    /**
     * 获取合作关系
     */
    @Override
    public Cooperate getCooperate(Account loginUser, String targetOrganizeId) {
        QueryWrapper<Cooperate> queryWrapper = new QueryWrapper<>();
        if (loginUser.getUserType() == UserType.shipperUser) {
            queryWrapper.eq("shipper_organize_id", loginUser.getOrganizeId());
            queryWrapper.eq("trucker_organize_id", targetOrganizeId);
        } else if (loginUser.getUserType() == UserType.truckerUser) {
            queryWrapper.eq("shipper_organize_id", targetOrganizeId);
            queryWrapper.eq("trucker_organize_id", loginUser.getOrganizeId());
        }
        return cooperateMapper.selectOne(queryWrapper);
    }

    /**
     * 获取合作車主分页
     */
    @Override
    public PageData<Organize> getCooperateOrganizePage(Account loginUser, Organize query, Integer page, Integer limit) {
        PageData<Organize> cooperateUserPage;
        if (loginUser.getUserType() == UserType.shipperUser) {
            cooperateUserPage = organizeMapper.getCooperateTruckerPage(loginUser, query, new PageData<>(page, limit));
            getOrganizePageData(loginUser, cooperateUserPage);
        } else if (loginUser.getUserType() == UserType.truckerUser) {
            cooperateUserPage = organizeMapper.getCooperateShipperPage(loginUser, query, new PageData<>(page, limit));
        } else throw new BusinessException("你没有可合作关系用户!");
        return cooperateUserPage;
    }

    /**
     * 获取同平台所有可合作用户分页
     */
    @Override
    public PageData<Organize> getPlatCanCooperateOrganizePage(Account loginUser, Organize query, Integer page, Integer limit) {
        PageData<Organize> cooperateUserPage;
        if (loginUser.getUserType() == UserType.shipperUser) {
            cooperateUserPage = organizeMapper.getPlatTruckerPage(loginUser, query, new PageData<>(page, limit));
        } else if (loginUser.getUserType() == UserType.truckerUser) {
            cooperateUserPage = organizeMapper.getPlatShipperPage(loginUser, query, new PageData<>(page, limit));
        } else throw new BusinessException("你没有可合作关系用户!");
        getOrganizePageData(loginUser, cooperateUserPage);
        return cooperateUserPage;
    }

    /**
     * 获取合作合作IDS
     * 用途：车主查询合作货源
     */
    @Override
    public List<String> getCooperateShipperIdList(String organizeId) {
        QueryWrapper<Cooperate> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("trucker_organize_id", organizeId);
        List<Cooperate> cooperateList = cooperateMapper.selectList(queryWrapper);
        return ArrayUtil.fieldAdd(cooperateList, Cooperate::getShipperOrganizeId);
    }

    //合作额外字段
    private void getOrganizePageData(Account loginUser, PageData<Organize> platTruckerPage) {
        for (Organize organize : platTruckerPage.getList()) {
            if (organize.getCooperateState() == null) {
                Cooperate cooperate = getCooperate(loginUser, organize.getId());
                if (cooperate==null) organize.setCooperateState(Cooperate.CooperateState.none);
                else organize.setCooperateState(cooperate.getCooperateState());
            }
            if (loginUser.getUserType() == UserType.shipperUser) {
                List<Account> employeeByOrganizeId = accountService.getEmployeeByOrganizeId(organize.getId());
                organize.setEmployeeCount(employeeByOrganizeId.size());
                List<TruckVehicle> truckVehicleList = ParamUtil.isSuccess(vehicleRemote.getVehicleListByOrganizeId(organize.getId()));
                StringBuilder res = new StringBuilder();
                for (TruckVehicle truckVehicle : truckVehicleList)
                    res.append(truckVehicle.getCommTruckTypeName()).append(",");
                int i = res.indexOf("null,");
                if (i == -1 && res.length() > 0) {
                    organize.setOwnTruckTypeNames(res.substring(0, res.length() - 1));
                }
            }
        }
    }

    @Override
    public void updateOrganize(Account loginUser, Organize organize, Organize localOrganize) {
        if (organize.getOrganizeName() != null) localOrganize.setOrganizeName(organize.getOrganizeName());
        if (organize.getOrganizeLogo() != null) localOrganize.setOrganizeLogo(organize.getOrganizeLogo());
        if (organize.getOrganizeTel() != null) localOrganize.setOrganizeTel(organize.getOrganizeTel());
        if (organize.getSignatureImg() != null) localOrganize.setSignatureImg(organize.getSignatureImg());
        if (organize.getIntroduction() != null) localOrganize.setIntroduction(organize.getIntroduction());
        if (organize.getLegalName() != null) localOrganize.setLegalName(organize.getLegalName());
        if (organize.getLegalPhone() != null) localOrganize.setLegalPhone(organize.getLegalPhone());
        if (organize.getAddress() != null) localOrganize.setAddress(organize.getAddress());
        localOrganize.setUpdateTime(new Date());
        localOrganize.setUpdateUserId(loginUser.getId());
        organizeMapper.updateById(localOrganize);
        //批量修改相同组织下的用户组织基本信息
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("organize_id", localOrganize.getId());
        List<Account> accountList = accountMapper.selectList(queryWrapper);
        for (Account account : accountList) {
            account.setOrganizeName(localOrganize.getOrganizeName());
            account.setOrganType(localOrganize.getOrganType());
            account.setOrganizeLogo(localOrganize.getOrganizeLogo());
            accountMapper.updateById(account);
        }
    }

    @Override
    public Organize getAdminOrganize() {
        QueryWrapper<Organize> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("user_type", UserType.yilinUser);
        return organizeMapper.selectOne(queryWrapper);
    }

    @Override
    public List<Organize> getOrganizeListByIds(String[] organizeIds) {
        return organizeMapper.selectBatchIds(ArrayUtil.initList(organizeIds));
    }

    @Override
    public List<Organize> getTruckOrganizeList() {
        QueryWrapper<Organize> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("authorized",true);
        queryWrapper.isNotNull("organize_name");
        return organizeMapper.selectList(queryWrapper);
    }

}
